﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using System.Web.Http;

using Microsoft.Practices.Unity;

using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Exporter.Controllers
{
	public class ExporterApiController : ApiController
	{
		public ExporterApiController(ERPStore.Logging.ILogger logger,
			ERPStore.Services.ICacheService cacheService)
		{
			this.Logger = logger;
			this.CacheService = cacheService;
		}

		protected ERPStore.Logging.ILogger Logger { get; private set; }
		protected ERPStore.Services.ICacheService CacheService { get; private set; }

		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public DateTime Ping()
		{
			return DateTime.Now;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string Generate(string id)
		{
			var key = string.Format("GenerateExport_{0}", id);
			var pg = CloudSoft.Workflows.ProgressReporterCollector.Get(key);

			if (pg != null)
			{
				throw new Exception(string.Format("generation already in progress"));
			}

			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();
			var exporter = list.FirstOrDefault(i => i.Name.Equals(id, StringComparison.InvariantCultureIgnoreCase));
			if (exporter == null)
			{
				return null;
			}

			var parameters = new Dictionary<string, object>();
			parameters.Add("ExportList", new List<ERPStore.Exporter.Providers.IExport>() { exporter });
			parameters.Add("ForceExport", true);

			pg = CloudSoft.Workflows.ProgressReporterCollector.GetNew();
			pg.Id = key;

			CloudSoft.Workflows.WorkflowQueueUserWorkItem.RunAsync(
				new ERPStore.Exporter.Workflows.GenerateCatalogs(),
				parameters,
				pg,
				null,
				(ex) =>
				{
					Logger.Error(ex);
				},
				null
			);

			return pg.Id;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public string GenerateAll(IList<string> exporterIdList)
		{
			var key = string.Format("ExportCatalog");
			var pg = CloudSoft.Workflows.ProgressReporterCollector.Get(key);

			if (pg != null)
			{
				throw new Exception(string.Format("generation already in progress"));
			}

			var exportList = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>().ToList();
			exportList.RemoveAll(i => i.Settings == null);
			exportList.RemoveAll(i => !i.Settings.Enabled);

			if (!exporterIdList.IsNullOrEmpty())
			{
				var exclusions = exportList.Select(i => i.LeadSource.Id).Except(exporterIdList).ToList();
				foreach (var item in exclusions)
				{
					var export = exportList.Single(i => i.LeadSource.Id == item);
					exportList.Remove(export);
				}
			}

			var parameters = new Dictionary<string, object>();
			parameters.Add("ExportList", exportList);
			parameters.Add("ForceExport", true);

			pg = CloudSoft.Workflows.ProgressReporterCollector.GetNew();
			pg.Id = key;

			CloudSoft.Workflows.WorkflowQueueUserWorkItem.RunAsync(
				new ERPStore.Exporter.Workflows.GenerateCatalogs(),
				parameters,
				pg,
				null,
				(ex) =>
				{
					Logger.Error(ex);
				},
				null
			);

			return pg.Id;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public ERPStore.Exporter.Models.Settings GetSettings(string id)
		{
			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();
			var exporter = list.FirstOrDefault(i => i.Name.Equals(id, StringComparison.InvariantCultureIgnoreCase));
			if (exporter == null)
			{
				return null;
			}

			return exporter.Settings;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public ERPStore.Exporter.Models.ExportInfo GetInfos(string id)
		{
			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();
			var exporter = list.FirstOrDefault(i => i.Name.Equals(id, StringComparison.InvariantCultureIgnoreCase));
			if (exporter == null)
			{
				return null;
			}

			var result = new ERPStore.Exporter.Models.ExportInfo();
			var path = ERPStore.Exporter.Configuration.ConfigurationSettings.AppSettings["exportPath"];
			var fileName = System.IO.Path.Combine(path, exporter.Settings.FileName);

			var fileInfo = new System.IO.FileInfo(fileName);

			if (!fileInfo.Exists)
			{
				result.FileName = "File does not exist";
				return result;
			}
			result.FileName = exporter.Settings.FileName;
			result.FileSize = string.Format("{0} Ko", fileInfo.Length / 1024);
			result.LastWriteTime = fileInfo.LastWriteTime;

			result.ProductCount = exporter.Settings.ProductCount;

			return result;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public IList<ERPStore.Exporter.Models.ExportInfo> GetExportInfoList()
		{
			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();

			var result = new List<ERPStore.Exporter.Models.ExportInfo>();
			foreach (var exporter in list)
			{
				var exportInfo = new ERPStore.Exporter.Models.ExportInfo();
				var path = ERPStore.Exporter.Configuration.ConfigurationSettings.AppSettings["exportPath"];
				var fileName = System.IO.Path.Combine(path, exporter.Settings.FileName);

				var fileInfo = new System.IO.FileInfo(fileName);

				if (fileInfo.Exists)
				{
					exportInfo.FileName = exporter.Settings.FileName;
					exportInfo.FileSize = string.Format("{0} Ko", fileInfo.Length / 1024);
					exportInfo.LastWriteTime = fileInfo.LastWriteTime;
				}
				else
				{
					exportInfo.FileName = "File does not exist";
				}
				exportInfo.LeadSouceId = exporter.LeadSource.Id;
				exportInfo.ProductCount = exporter.Settings.ProductCount;

				result.Add(exportInfo);
			}

			return result;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpGet]
		[System.Web.Http.HttpPost]
		public Dictionary<string,ERPStore.Exporter.Models.Settings> GetExportSettingsList()
		{
			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();
			var result = list.ToDictionary(i => i.LeadSource.Id, j => j.Settings);
			return result;
		}

		[ERPStore.Web.Controllers.ActionFilters.ApiAuthorizedOperation]
		[System.Web.Http.HttpPost]
		[System.Web.Http.HttpPut]
		public bool SaveSettings(string id, [FromBody] ERPStore.Exporter.Models.Settings settings)
		{
			var list = GlobalConfiguration.Configuration.DependencyResolver.GetServices<ERPStore.Exporter.Providers.IExport>();
			var exporter = list.FirstOrDefault(i => i.Name.Equals(id, StringComparison.InvariantCultureIgnoreCase));
			if (exporter == null)
			{
				return false;
			}

			exporter.Settings.AllowMissingDefaultImage = settings.AllowMissingDefaultImage;
			exporter.Settings.AllowNotSellable = settings.AllowNotSellable;
			exporter.Settings.AllowNullLongDescription = settings.AllowNullLongDescription;
			exporter.Settings.AllowNullShortDescription = settings.AllowNullShortDescription;
			exporter.Settings.AllowNullStrengthsPoints = settings.AllowNullStrengthsPoints;
			exporter.Settings.AllowStockEmpty = settings.AllowStockEmpty;
			exporter.Settings.AllowVariant = settings.AllowVariant;
			exporter.Settings.AllowVariation = settings.AllowVariation;
			exporter.Settings.AllowZeroSalePrice = settings.AllowZeroSalePrice;
			exporter.Settings.BarcodeMandatory = settings.BarcodeMandatory;
			exporter.Settings.Enabled = settings.Enabled;
			exporter.Settings.FileName = settings.FileName;
			exporter.Settings.RestrictToOrdered = settings.RestrictToOrdered;
			exporter.Settings.RestrictToOrderedBySource = settings.RestrictToOrderedBySource;
			exporter.Settings.MinimalSalePrice = settings.MinimalSalePrice;
			exporter.Settings.MaximumSalePrice = settings.MaximumSalePrice;

			exporter.SaveSettings();

			return true;
		}
	}
}
